package com.xmut.xmutbackend.Interceptor;

import com.xmut.xmutbackend.service.IOperationLogService;
import com.xmut.xmutbackend.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 专门用于记录所有接口访问日志的拦截器
 * 与身份验证拦截器分开，确保所有请求（包括登录和公共API）都能被记录
 */
@Component
public class LoggingInterceptor implements HandlerInterceptor {

    @Autowired
    private IOperationLogService logService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 开始时间
        request.setAttribute("startTime", System.currentTimeMillis());
        return true; // 始终放行，不影响请求处理
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 获取请求处理时间
        long startTime = (Long) request.getAttribute("startTime");
        long duration = System.currentTimeMillis() - startTime;

        // 获取请求信息
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String ip = getClientIp(request);
        
        // 尝试获取token
        String token = request.getHeader("token");
        
        // 记录日志（包括请求时间）
        if (StringUtils.hasLength(token)) {
            try {
                // 尝试解析token
                Claims claims = JwtUtils.parseJWT(token);
                Long userId = Long.valueOf(claims.get("id").toString());
                String username = claims.get("username").toString();
                
                // 记录成功访问日志
                logService.recordLog(userId, username, method, uri + " (" + duration + "ms)", ip, 1);
            } catch (ExpiredJwtException e) {
                // 从过期的JWT中提取用户信息
                Claims claims = e.getClaims();
                if (claims != null) {
                    Long userId = Long.valueOf(claims.get("id").toString());
                    String username = claims.get("username").toString();
                    // 记录过期token访问
                    logService.recordLog(userId, username, method, uri + " (" + duration + "ms)", ip, 0);
                }
            } catch (Exception e) {
                // 记录无效token访问
                logService.recordLog(null, "无效Token", method, uri + " (" + duration + "ms)", ip, 0);
            }
        } else {
            // 记录无token访问
            String path = uri.toLowerCase();
            
            // 对登录请求特殊处理
            if (path.contains("/login") || path.contains("/users/login")) {
                logService.recordLog(null, "登录请求", method, uri + " (" + duration + "ms)", ip, 
                        response.getStatus() == 200 ? 1 : 0);
            } else {
                // 其他公共接口访问
                logService.recordLog(null, "公共访问", method, uri + " (" + duration + "ms)", ip, 
                        response.getStatus() == 200 ? 1 : 0);
            }
        }
    }

    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
} 